#include <iostream>
#include <unistd.h>
#include <signal.h>


void PrintPending(const sigset_t &pending)
{
    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&pending, signo))//如果signo信号在pending集合里
        {
            std::cout << "1";//在的话输出1
        }
        else
        {
            std::cout << "0";
        }
    }
    std::cout << "\n";
}
void handler(int signo)//为了便于测试，更改2号信号的默认行为
{
    std::cout << "handler " << signo << std::endl;
    // exit(100);
}
int main()
{
    signal(2, handler);

    std::cout << "getpid: " << getpid() << std::endl;

    // 1. 屏蔽2号信号
    sigset_t set, oset;
    sigemptyset(&set);
    sigemptyset(&oset);
    sigaddset(&set, 2);//将2号信号添加到set
    sigprocmask(SIG_BLOCK, &set, &oset);

    // 2. 让进程不断获取当前进程的pending
    int cnt = 0;
    sigset_t pending;
    while(true)
    {
        sigpending(&pending);
        PrintPending(pending);

        sleep(1);

        cnt++;

        if(cnt == 5)
        {
            std::cout << "解除对2号信号的屏蔽, 2号信号准备递达" << std::endl;
            sigprocmask(SIG_SETMASK, &oset, nullptr);//先前保存了旧的信号，现在可以恢复
        }
    }



    // std::cout << "getpid: " << getpid() << std::endl;
    // signal(2, handler);
    // sigset_t block, oblock;
    // sigemptyset(&block);//位图全部置为0（清空信号）
    // sigemptyset(&oblock);
    // //尝试屏蔽所有的普通信号（测试发现9号信号不能被屏蔽，还可以杀死进程；19号信号可以暂停进程，其余的都被屏蔽）
    // for(int signo = 1; signo <= 31; signo++) sigaddset(&block, signo);//这条语句还没有设置对信号的屏蔽，只是对栈上的局部变量进行了设置
    // sigprocmask(SIG_SETMASK, &block, &oblock);//完成对信号的屏蔽
    // while(true)
    // {
    //     std::cout << "我已经屏蔽了所有的信号, 来打我啊！" << std::endl;
    //     sleep(1);
    // }



    // std::cout << "getpid: " << getpid() << std::endl;
    // signal(2, handler);//信号的自定义捕捉
    // signal(2, SIG_IGN);//信号的忽略，比如“CTRL + C”会失效（Ignore signal）
    // signal(2, SIG_DFL);//恢复信号的默认行为（Default action）


    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // while(true)
    // {
    //     sleep(1);
    // }
    // int a = 10;
    // a /= 0;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;
    // std::cout << "getpid: " << getpid() << std::endl;

    return 0;
}



// void handler(int signo)//为了便于测试，更改2号信号的默认行为
// {
//     sigset_t pending;

//     std::cout << "###############################"<< std::endl;
//     sigpending(&pending);//在此处打印pending位图，可以发现在比特位都为0，也就是说信号在执行自定义捕捉方法之前，pending比特位已经改成0了
//     PrintPending(pending);
//     std::cout << "###############################"<< std::endl;

//     std::cout << "handler " << signo << std::endl;
// }
// int main()
// {
//     signal(2, handler);

//     while(true)
//     {
//         sleep(1);
//     }
    
//     return 0;
// }
